package com.yzk.train.business.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yzk.train.business.entity.DailyTrain;
import com.yzk.train.business.entity.DailyTrainExample;
import com.yzk.train.business.entity.Train;
import com.yzk.train.business.mapper.DailyTrainMapper;
import com.yzk.train.business.request.DailyTrainQueryReq;
import com.yzk.train.business.request.DailyTrainSaveReq;
import com.yzk.train.business.response.DailyTrainQueryResp;
import com.yzk.train.common.response.PageResp;
import com.yzk.train.common.utils.SnowUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class DailyTrainService {

    private static final Logger LOG = LoggerFactory.getLogger(DailyTrainService.class);

    @Resource
    private DailyTrainMapper dailyTrainMapper;

    @Resource
    private TrainService trainService;

    @Resource
    private DailyTrainStationService dailyTrainStationService;

    @Resource
    private DailyTrainCarriageService dailyTrainCarriageService;

    @Resource
    private DailyTrainSeatService dailyTrainSeatService;

    @Resource
    private DailyTrainTicketService dailyTrainTicketService;

    /**
     * 保存 / 更新 每日车次
     *
     * @param req
     */
    public String save(DailyTrainSaveReq req) {
        DailyTrain dailyTrain = BeanUtil.copyProperties(req, DailyTrain.class);
        DateTime now = DateTime.now();
        dailyTrain.setUpdateTime(now);
        if (ObjectUtil.isNull(dailyTrain.getId())) {
            dailyTrain.setId(SnowUtil.getSnowflakeNextId());
            dailyTrain.setCreateTime(now);
            dailyTrainMapper.insert(dailyTrain);
            return "保存成功";
        } else {
            dailyTrainMapper.updateByPrimaryKeySelective(dailyTrain);
            return "编辑成功";
        }
    }

    /**
     * 查询每日车次列表
     *
     * @param req
     */
    public PageResp<DailyTrainQueryResp> queryList(DailyTrainQueryReq req) {
        DailyTrainExample dailyTrainExample = new DailyTrainExample();
        dailyTrainExample.setOrderByClause("date desc, code asc");
        DailyTrainExample.Criteria criteria = dailyTrainExample.createCriteria();
        // 如果有参，就按照 日期 / 车次编号 查询
        if (ObjectUtil.isNotNull(req.getDate())) {
            criteria.andDateEqualTo(req.getDate());
        }
        if (ObjectUtil.isNotEmpty(req.getCode())) {
            criteria.andCodeEqualTo(req.getCode());
        }
        // 使用分页插件
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        List<DailyTrain> dailyTrains = dailyTrainMapper.selectByExample(dailyTrainExample);
        // 使用 PageInfo 包装查询结果
        PageInfo<DailyTrain> pageInfo = new PageInfo<>(dailyTrains);
        // 转换为 PageResp
        List<DailyTrainQueryResp> list = BeanUtil.copyToList(dailyTrains, DailyTrainQueryResp.class);
        return new PageResp<>(pageInfo.getTotal(), list);
    }

    /**
     * 根据ID删除每日车次
     * @param id
     */
    public void delete(Long id) {
        dailyTrainMapper.deleteByPrimaryKey(id);
    }

    /**
     * 生成某日所有车次信息，包括车次、车站、车厢、座位
     * @param date 要生成的日期
     */
    public void genDaily(Date date) {
        List<Train> trainList = trainService.queryAllNotResp();
        if (CollUtil.isEmpty(trainList)) {
            LOG.info("没有车次基础数据，任务结束");
            return;
        }

        for (Train train : trainList) {
            genDailyTrain(date, train);
        }
    }

    /**
     * 开启事务，生成某日某车次的所有信息，包括车次、车站、车厢、座位
     * @param date 要生成的日期
     */
    @Transactional
    public void genDailyTrain(Date date, Train train) {
        // 删除该车次已有的数据
        DailyTrainExample dailyTrainExample = new DailyTrainExample();
        dailyTrainExample.createCriteria()
                .andDateEqualTo(date)
                .andCodeEqualTo(train.getCode());
        dailyTrainMapper.deleteByExample(dailyTrainExample);

        // 生成该车次的数据
        DateTime now = DateTime.now();
        DailyTrain dailyTrain = BeanUtil.copyProperties(train, DailyTrain.class);
        dailyTrain.setId(SnowUtil.getSnowflakeNextId());
        dailyTrain.setCreateTime(now);
        dailyTrain.setUpdateTime(now);
        dailyTrain.setDate(date);
        dailyTrainMapper.insert(dailyTrain);

        // 生成该车次的车站数据
        dailyTrainStationService.genDaily(date, train.getCode());

        // 生成该车次的车厢数据
        dailyTrainCarriageService.genDaily(date, train.getCode());

        // 生成该车次的座位数据
        dailyTrainSeatService.genDaily(date, train.getCode());

        // 生成该车次的余票数据
        dailyTrainTicketService.genDaily(dailyTrain, date, train.getCode());

        LOG.info("生成日期【{}】，生成车次【{}】", DateUtil.formatDate(date), train.getCode());
    }

}
